home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / demos / GL / snurb / pick.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  6.7 KB  |  320 lines

  1. /*
  2.  * Copyright 1991, 1992, 1993, 1994, Silicon Graphics, Inc.
  3.  * All Rights Reserved.
  4.  *
  5.  * This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
  6.  * the contents of this file may not be disclosed to third parties, copied or
  7.  * duplicated in any form, in whole or in part, without the prior written
  8.  * permission of Silicon Graphics, Inc.
  9.  *
  10.  * RESTRICTED RIGHTS LEGEND:
  11.  * Use, duplication or disclosure by the Government is subject to restrictions
  12.  * as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
  13.  * and Computer Software clause at DFARS 252.227-7013, and/or in similar or
  14.  * successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
  15.  * rights reserved under the Copyright Laws of the United States.
  16.  */
  17. /* pick.c */
  18.  
  19.  
  20. #include <gl.h>
  21. #include <stdio.h>
  22. #include "defines.h"
  23. #include "draw.h"
  24. #include "snurb.h"
  25. #include "nurb.h"
  26. #include "draw.h"
  27. #include "pick.h"
  28.  
  29. extern Coord cube_vertex[8][3];
  30. extern Matrix view_matrix;
  31. extern struct node_struct *root, *selected_patch, *zip_dest;
  32.  
  33. static void draw_volume(void);
  34. static void find_patch_and_point(
  35.     struct node_struct *child, 
  36.     unsigned long *color,
  37.     unsigned long target, 
  38.     struct node_struct **result, 
  39.     int *s_ptr, int *t_ptr);
  40. static void draw_clean_control_points(
  41.     struct node_struct *child, unsigned long *color);
  42. static void draw_clean_objects(struct node_struct *child, unsigned long *color);
  43. static void find_root_object(struct node_struct *child,
  44.     struct node_struct **object);
  45. static void find_object(struct node_struct *child, 
  46.     unsigned long *color, unsigned long target, struct node_struct **object);
  47.  
  48.  
  49. /*
  50.  * Draws the view volume using polygons with no vertex color(used in pick mode)
  51.  */
  52. static void draw_volume(void)
  53. {
  54.     
  55.     /* x = 1.0 */
  56.     bgnpolygon();
  57.     v3f(cube_vertex[4]);
  58.     v3f(cube_vertex[5]);
  59.     v3f(cube_vertex[6]);
  60.     v3f(cube_vertex[7]);
  61.     endpolygon();
  62.  
  63.     /* x = -1.0 */
  64.     bgnpolygon();
  65.     v3f(cube_vertex[0]);
  66.     v3f(cube_vertex[1]);
  67.     v3f(cube_vertex[2]);
  68.     v3f(cube_vertex[3]);
  69.     endpolygon();
  70.  
  71.     /* y = 1.0 */
  72.     bgnpolygon();
  73.     v3f(cube_vertex[3]);
  74.     v3f(cube_vertex[2]);
  75.     v3f(cube_vertex[6]);
  76.     v3f(cube_vertex[7]);
  77.     endpolygon();
  78.  
  79.     /* y = -1.0 */
  80.     bgnpolygon();
  81.     v3f(cube_vertex[0]);
  82.     v3f(cube_vertex[1]);
  83.     v3f(cube_vertex[5]);
  84.     v3f(cube_vertex[4]);
  85.     endpolygon();
  86.  
  87.     /* z = 1.0 */
  88.     bgnpolygon();
  89.     v3f(cube_vertex[1]);
  90.     v3f(cube_vertex[2]);
  91.     v3f(cube_vertex[6]);
  92.     v3f(cube_vertex[5]);
  93.     endpolygon();
  94.  
  95.     /* z = -1.0 */
  96.     bgnpolygon();
  97.     v3f(cube_vertex[0]);
  98.     v3f(cube_vertex[3]);
  99.     v3f(cube_vertex[7]);
  100.     v3f(cube_vertex[4]);
  101.     endpolygon();
  102. }
  103.  
  104.  
  105. static void find_patch_and_point(
  106.     struct node_struct *child, 
  107.     unsigned long *color,
  108.     unsigned long target, 
  109.     struct node_struct **result, 
  110.     int *s_ptr, int *t_ptr)
  111. {
  112.     int s,t;
  113.     
  114.     if ((child != NULL) && (*result == NULL))
  115.     {
  116.         if ((child->node_type == PATCH) && (child != zip_dest))
  117.         {
  118.             for(s = 0; s< NUMPOINTS; s++)
  119.                     for(t = 0; t < NUMPOINTS; t++)
  120.                     {
  121.                         if (*color == target)
  122.                         {
  123.                             *result = child;
  124.                             *s_ptr = s; *t_ptr = t;
  125.                             
  126.                             s = t = NUMPOINTS; /* outta here */
  127.                         }
  128.                         else
  129.                             cpack((*color)++);
  130.                     }
  131.         }
  132.  
  133.         find_patch_and_point(child->child, color, target, result,s_ptr,t_ptr);
  134.         find_patch_and_point(child->sibling, color, target,result,s_ptr,t_ptr);
  135.     }
  136. }
  137.     
  138.  
  139.  
  140.  
  141. static void draw_clean_control_points(
  142.     struct node_struct *child, unsigned long *color)
  143. {
  144.     int s,t;
  145.     
  146.     if (child != NULL)
  147.     {
  148.         if ((child->node_type == PATCH) && (child != zip_dest))
  149.         {
  150.             for(s = 0; s< NUMPOINTS; s++)
  151.                     for(t = 0; t < NUMPOINTS; t++)
  152.                     {
  153.                         pushmatrix();
  154.             
  155.                         translate(
  156.                             child->patch->control[s][t][0],
  157.                             child->patch->control[s][t][1],
  158.                             child->patch->control[s][t][2]);
  159.                             
  160.                         scale(.02, .02, .02);
  161.             
  162.                         cpack((*color)++);
  163.                         draw_volume();
  164.                         
  165.                         popmatrix();
  166.                     }
  167.         }
  168.  
  169.         draw_clean_control_points(child->child, color);
  170.         draw_clean_control_points(child->sibling, color);
  171.     }
  172. }
  173.  
  174.  
  175.  
  176.  
  177. /* 
  178.  * For the given object, draw all of its (and childrens) patches
  179.  * and determine which control point on which patch the mouse is over.
  180.  * If none, will return NULL, else will return pointer to the node
  181.  * (node_type == PATCH) and will set s and t to the coordinates of
  182.  * the selected control point.
  183.  */
  184. struct node_struct *pick_patch_control(
  185.     struct node_struct *child,
  186.     Scoord mx, Scoord my,
  187.     int *s_ptr, int *t_ptr)
  188. {
  189.     unsigned long val, color;
  190.     struct node_struct *result;
  191.     
  192.     clear_window();
  193.     set_view(MVIEWING);
  194.     multmatrix(view_matrix);
  195.  
  196.     color = 1;
  197.  
  198.     if (child != NULL)
  199.         draw_clean_control_points(child, &color);
  200.  
  201.     readsource(SRC_BACK);
  202.     lrectread(mx,my,mx,my,&val);
  203.  
  204.     result = NULL;
  205.     
  206.     if (val)
  207.     {
  208.         color = 1;
  209.         
  210.         find_patch_and_point(child,&color,val,&result, s_ptr, t_ptr);
  211.     }
  212.     
  213.     return result;
  214.  
  215. }
  216.  
  217.  
  218.  
  219.  
  220.     
  221.  
  222. /* Starting with child, draws all its and its descendant's and sibling's 
  223.  * patches with sucessive colors.
  224.  */
  225. static void draw_clean_objects(struct node_struct *child, unsigned long *color)
  226. {
  227.     if (child != NULL)
  228.     {
  229.         if (child->node_type == PATCH)
  230.         {
  231.             cpack((*color)++);
  232.             draw_patch(child->patch->control);
  233.         }
  234.  
  235.         draw_clean_objects(child->child, color);
  236.         draw_clean_objects(child->sibling, color);
  237.     }
  238. }
  239.  
  240.  
  241. /* Finds the root-most ancestor of child and makes object point to it. That is,
  242.  * object will point to the node that is a child of root, and an ancestor of
  243.  * child.
  244.  */
  245. static void find_root_object(struct node_struct *child,
  246.     struct node_struct **object)
  247. {
  248.     if (child->parent == root)
  249.         *object = child;
  250.     else
  251.         find_root_object(child->parent, object);
  252. }
  253.  
  254.  
  255.  
  256. /* Starting with child, checks to see if the current node would have produced
  257.  * the target color. If so, makes object point to the root-most object that is
  258.  * an ancestor of child. If not, recurses on child's decendants
  259.  * and siblings until the target color is found.
  260.  */
  261. static void find_object(struct node_struct *child, 
  262.     unsigned long *color, unsigned long target, struct node_struct **object)
  263. {
  264.     if ((child != NULL) && (*object == NULL))
  265.     {
  266.         if (child->node_type == PATCH)
  267.         {
  268.             if (*color == target)
  269.                 find_root_object(child, object);
  270.             else
  271.                 (*color)++;
  272.         }
  273.  
  274.         find_object(child->child, color, target, object);
  275.         find_object(child->sibling, color, target, object);
  276.     }
  277. }
  278.  
  279.  
  280.  
  281.  
  282. /* Returns a pointer to the object node underneath the mouse, if any. 
  283.  * Returns NULL if none.
  284.  */
  285. struct node_struct *pick_object(Scoord mx, Scoord my)
  286. {
  287.     unsigned long val, color;
  288.     struct node_struct *result;
  289.  
  290.     
  291.     lmbind(MATERIAL, 0);
  292.  
  293.     setnurbsproperty(N_PIXEL_TOLERANCE, PICKING_TOLERANCE);
  294.     
  295.     clear_window();
  296.     set_view(MVIEWING);
  297.     multmatrix(view_matrix);
  298.  
  299.     /* draw only the surface, no control points, etc */
  300.     color = 1;
  301.     draw_clean_objects(root->child, &color);
  302.  
  303.     readsource(SRC_BACK);
  304.     lrectread(mx,my,mx,my,&val);
  305.  
  306.     result = NULL;
  307.     
  308.     if (val)
  309.     {
  310.         color = 1;
  311.         find_object(root->child, &color, val, &result);
  312.     }
  313.     
  314.     return result;
  315. }
  316.  
  317.  
  318.  
  319.  
  320.